#!/bin/bash

# Flink Web Analytics 一键启动脚本
# 同时启动后端API服务和前端开发服务器

set -e

# 检查是否在正确的目录
if [ ! -f "run.sh" ]; then
    echo "❌ 请在项目根目录下运行此脚本"
    exit 1
fi

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 项目根目录
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BACKEND_DIR="$PROJECT_ROOT/backend"
FRONTEND_DIR="$PROJECT_ROOT/frontend"

# PID文件路径
BACKEND_PID_FILE="$PROJECT_ROOT/backend.pid"
FRONTEND_PID_FILE="$PROJECT_ROOT/frontend.pid"

# 日志文件路径
LOGS_DIR="$PROJECT_ROOT/logs"
BACKEND_LOG="$LOGS_DIR/backend.log"
FRONTEND_LOG="$LOGS_DIR/frontend.log"
BACKEND_ERROR_LOG="$LOGS_DIR/backend_error.log"
STARTUP_LOG="$LOGS_DIR/startup.log"

# 创建日志目录和初始化
mkdir -p "$LOGS_DIR"

# 日志函数
log_message() {
    local level=$1
    local message=$2
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[$timestamp] [$level] $message" >> "$STARTUP_LOG"
}

# 检查依赖
check_dependencies() {
    log_message "INFO" "检查系统依赖..."
    
    # 检查Python
    if ! command -v python3 &> /dev/null; then
        print_message $RED "❌ Python3 未安装，请先安装 Python 3.8+"
        log_message "ERROR" "Python3 未安装"
        return 1
    fi
    
    local python_version=$(python3 --version 2>&1 | cut -d' ' -f2)
    log_message "INFO" "Python版本: $python_version"
    
    # 检查Node.js
    if ! command -v node &> /dev/null; then
        print_message $RED "❌ Node.js 未安装，请先安装 Node.js >= 16.0.0"
        log_message "ERROR" "Node.js 未安装"
        return 1
    fi
    
    local node_version=$(node --version 2>&1)
    log_message "INFO" "Node.js版本: $node_version"
    
    return 0
}

# 打印带颜色的消息
print_message() {
    local color=$1
    local message=$2
    echo -e "${color}${message}${NC}"
}

# 检查端口是否被占用
check_port() {
    local port=$1
    if lsof -Pi :$port -sTCP:LISTEN -t >/dev/null 2>&1; then
        return 0  # 端口被占用
    else
        return 1  # 端口空闲
    fi
}

# 启动后端服务
start_backend() {
    print_message $BLUE "🚀 启动后端API服务..."
    log_message "INFO" "开始启动后端服务"
    
    # 检查后端目录
    if [ ! -d "$BACKEND_DIR" ]; then
        print_message $RED "❌ 后端目录不存在: $BACKEND_DIR"
        log_message "ERROR" "后端目录不存在: $BACKEND_DIR"
        exit 1
    fi
    
    # 检查端口5001是否被占用
    if check_port 8096; then
        print_message $YELLOW "⚠️  端口5001已被占用，尝试停止现有服务..."
        log_message "WARN" "端口5001已被占用，尝试停止现有服务"
        stop_backend
        sleep 2
    fi
    
    # 进入后端目录
    cd "$BACKEND_DIR"
    log_message "INFO" "进入后端目录: $BACKEND_DIR"
    
    # 检查虚拟环境
    if [ ! -d "venv" ]; then
        print_message $YELLOW "📦 创建Python虚拟环境..."
        log_message "INFO" "创建Python虚拟环境"
        python3 -m venv venv
        if [ $? -ne 0 ]; then
            print_message $RED "❌ 创建虚拟环境失败"
            log_message "ERROR" "创建虚拟环境失败"
            exit 1
        fi
    fi
    
    # 激活虚拟环境
    source venv/bin/activate
    log_message "INFO" "激活虚拟环境"
    
    # 检查requirements.txt
    if [ ! -f "requirements.txt" ]; then
        print_message $RED "❌ requirements.txt 文件不存在"
        log_message "ERROR" "requirements.txt 文件不存在"
        exit 1
    fi
    
    # 安装依赖
    print_message $YELLOW "📦 安装后端依赖..."
    log_message "INFO" "开始安装后端依赖"
    pip install -r requirements.txt >> "$STARTUP_LOG" 2>&1
    if [ $? -ne 0 ]; then
        print_message $RED "❌ 安装依赖失败，请检查日志: $STARTUP_LOG"
        log_message "ERROR" "安装依赖失败"
        exit 1
    fi
    
    # 检查run.py
    if [ ! -f "run.py" ]; then
        print_message $RED "❌ run.py 文件不存在"
        log_message "ERROR" "run.py 文件不存在"
        exit 1
    fi
    
    # 启动后端服务
    print_message $GREEN "✅ 启动后端服务 (端口: 8096)..."
    log_message "INFO" "启动后端服务"
    nohup python run.py > "$BACKEND_LOG" 2> "$BACKEND_ERROR_LOG" &
    local backend_pid=$!
    echo $backend_pid > "$BACKEND_PID_FILE"
    log_message "INFO" "后端服务PID: $backend_pid"
    
    # 等待服务启动
    print_message $YELLOW "⏳ 等待后端服务启动..."
    local max_wait=30
    local wait_count=0
    
    while [ $wait_count -lt $max_wait ]; do
        if check_port 8096; then
            break
        fi
        sleep 1
        wait_count=$((wait_count + 1))
        echo -n "."
    done
    echo ""
    
    # 检查服务是否启动成功
    if check_port 8096; then
        print_message $GREEN "✅ 后端服务启动成功! (PID: $backend_pid)"
        log_message "INFO" "后端服务启动成功"
        
        # 测试API连接
        if curl -s "http://localhost:8096/api/health" > /dev/null 2>&1; then
            print_message $GREEN "✅ 后端API健康检查通过"
            log_message "INFO" "后端API健康检查通过"
        else
            print_message $YELLOW "⚠️  后端API健康检查失败，但服务已启动"
            log_message "WARN" "后端API健康检查失败"
        fi
    else
        print_message $RED "❌ 后端服务启动失败，请检查日志:"
        print_message $RED "   主日志: $BACKEND_LOG"
        print_message $RED "   错误日志: $BACKEND_ERROR_LOG"
        print_message $RED "   启动日志: $STARTUP_LOG"
        log_message "ERROR" "后端服务启动失败"
        
        # 显示错误日志的最后几行
        if [ -f "$BACKEND_ERROR_LOG" ]; then
            echo ""
            print_message $RED "最近的错误信息:"
            tail -5 "$BACKEND_ERROR_LOG" | while read line; do
                print_message $RED "  $line"
            done
        fi
        
        exit 1
    fi
}

# 启动前端服务
start_frontend() {
    print_message $BLUE "🚀 启动前端开发服务器..."
    log_message "INFO" "开始启动前端服务"
    
    # 检查前端目录
    if [ ! -d "$FRONTEND_DIR" ]; then
        print_message $RED "❌ 前端目录不存在: $FRONTEND_DIR"
        log_message "ERROR" "前端目录不存在: $FRONTEND_DIR"
        exit 1
    fi
    
    # 进入前端目录
    cd "$FRONTEND_DIR"
    log_message "INFO" "进入前端目录: $FRONTEND_DIR"
    
    # 检查package.json
    if [ ! -f "package.json" ]; then
        print_message $RED "❌ package.json 文件不存在"
        log_message "ERROR" "package.json 文件不存在"
        exit 1
    fi
    
    # 检查依赖是否安装
    if [ ! -d "node_modules" ]; then
        print_message $YELLOW "📦 安装前端依赖..."
        log_message "INFO" "开始安装前端依赖"
        npm install >> "$STARTUP_LOG" 2>&1
        if [ $? -ne 0 ]; then
            print_message $RED "❌ 安装前端依赖失败，请检查日志: $STARTUP_LOG"
            log_message "ERROR" "安装前端依赖失败"
            exit 1
        fi
    fi
    
    # 检查前端端口是否被占用
    local frontend_ports=(5173 5174 5175)
    for port in "${frontend_ports[@]}"; do
        if check_port $port; then
            print_message $YELLOW "⚠️  端口$port已被占用，尝试停止现有服务..."
            log_message "WARN" "端口$port已被占用"
            local port_pid=$(lsof -ti:$port)
            if [ -n "$port_pid" ]; then
                kill -9 $port_pid
                sleep 1
            fi
        fi
    done
    
    # 启动前端服务
    print_message $GREEN "✅ 启动前端服务..."
    log_message "INFO" "启动前端服务"
    nohup npm run dev > "$FRONTEND_LOG" 2>&1 &
    local frontend_pid=$!
    echo $frontend_pid > "$FRONTEND_PID_FILE"
    log_message "INFO" "前端服务PID: $frontend_pid"
    
    # 等待服务启动
    print_message $YELLOW "⏳ 等待前端服务启动..."
    local max_wait=30
    local wait_count=0
    local frontend_port=""
    
    while [ $wait_count -lt $max_wait ]; do
        # 检查各个可能的端口
        for port in "${frontend_ports[@]}"; do
            if check_port $port; then
                frontend_port=$port
                break
            fi
        done
        
        if [ -n "$frontend_port" ]; then
            break
        fi
        
        sleep 1
        wait_count=$((wait_count + 1))
        echo -n "."
    done
    echo ""
    
    if [ -n "$frontend_port" ]; then
        print_message $GREEN "✅ 前端服务启动成功! (端口: $frontend_port, PID: $frontend_pid)"
        log_message "INFO" "前端服务启动成功，端口: $frontend_port"
        
        # 测试前端连接
        if curl -s "http://localhost:$frontend_port" > /dev/null 2>&1; then
            print_message $GREEN "✅ 前端服务健康检查通过"
            log_message "INFO" "前端服务健康检查通过"
        else
            print_message $YELLOW "⚠️  前端服务健康检查失败，但服务已启动"
            log_message "WARN" "前端服务健康检查失败"
        fi
    else
        print_message $YELLOW "⚠️  前端服务可能正在启动中，请稍后检查日志: $FRONTEND_LOG"
        log_message "WARN" "前端服务启动超时"
        
        # 显示前端日志的最后几行
        if [ -f "$FRONTEND_LOG" ]; then
            echo ""
            print_message $YELLOW "最近的前端日志:"
            tail -5 "$FRONTEND_LOG" | while read line; do
                print_message $YELLOW "  $line"
            done
        fi
    fi
}

# 停止后端服务
stop_backend() {
    if [ -f "$BACKEND_PID_FILE" ]; then
        local pid=$(cat "$BACKEND_PID_FILE")
        if ps -p $pid > /dev/null 2>&1; then
            print_message $YELLOW "🛑 停止后端服务 (PID: $pid)..."
            kill $pid
            rm -f "$BACKEND_PID_FILE"
            print_message $GREEN "✅ 后端服务已停止"
        else
            rm -f "$BACKEND_PID_FILE"
        fi
    fi
    
    # 强制杀死占用5001端口的进程
    local port_pid=$(lsof -ti:8096)
    if [ -n "$port_pid" ]; then
        print_message $YELLOW "🛑 强制停止占用端口5001的进程..."
        kill -9 $port_pid
    fi
}

# 停止前端服务
stop_frontend() {
    if [ -f "$FRONTEND_PID_FILE" ]; then
        local pid=$(cat "$FRONTEND_PID_FILE")
        if ps -p $pid > /dev/null 2>&1; then
            print_message $YELLOW "🛑 停止前端服务 (PID: $pid)..."
            kill $pid
            rm -f "$FRONTEND_PID_FILE"
            print_message $GREEN "✅ 前端服务已停止"
        else
            rm -f "$FRONTEND_PID_FILE"
        fi
    fi
    
    # 强制杀死占用5173-5175端口的进程
    for port in 5173 5174 5175; do
        local port_pid=$(lsof -ti:$port)
        if [ -n "$port_pid" ]; then
            print_message $YELLOW "🛑 强制停止占用端口$port的进程..."
            kill -9 $port_pid
        fi
    done
}

# 显示服务状态
show_status() {
    print_message $BLUE "📊 服务状态:"
    echo ""
    
    # 检查后端状态
    if check_port 8096; then
        print_message $GREEN "✅ 后端服务: 运行中 (端口: 8096)"
    else
        print_message $RED "❌ 后端服务: 未运行"
    fi
    
    # 检查前端状态
    local frontend_running=false
    for port in 5173 5174 5175; do
        if check_port $port; then
            print_message $GREEN "✅ 前端服务: 运行中 (端口: $port)"
            frontend_running=true
            break
        fi
    done
    
    if [ "$frontend_running" = false ]; then
        print_message $RED "❌ 前端服务: 未运行"
    fi
    
    echo ""
    print_message $BLUE "📁 日志文件:"
    echo "  后端日志: $BACKEND_LOG"
    echo "  前端日志: $FRONTEND_LOG"
}

# 显示帮助信息
show_help() {
    echo "Flink Web Analytics 一键启动脚本"
    echo ""
    echo "用法: $0 [选项] [参数]"
    echo ""
    echo "选项:"
    echo "  start       启动前后端服务 (默认)"
    echo "  stop        停止前后端服务"
    echo "  restart     重启前后端服务"
    echo "  status      显示服务状态"
    echo "  logs        查看服务日志"
    echo "  clean       清理所有日志文件"
    echo "  help        显示帮助信息"
    echo ""
    echo "日志选项:"
    echo "  logs [类型] [行数]"
    echo "    类型: all(默认) | backend | frontend | startup"
    echo "    行数: 显示的日志行数 (默认: 20)"
    echo ""
    echo "示例:"
    echo "  $0                    # 启动服务"
    echo "  $0 start              # 启动服务"
    echo "  $0 stop               # 停止服务"
    echo "  $0 restart            # 重启服务"
    echo "  $0 status             # 查看状态"
    echo "  $0 logs               # 查看所有日志"
    echo "  $0 logs backend       # 查看后端日志"
    echo "  $0 logs frontend 50   # 查看前端日志最后50行"
    echo "  $0 clean              # 清理日志文件"
    echo ""
    echo "服务端口:"
    echo "  后端API:  http://localhost:8096"
    echo "  前端界面: http://localhost:5173 (或 5174, 5175)"
    echo ""
    echo "日志文件位置:"
    echo "  $LOGS_DIR/"
}

# 查看日志
show_logs() {
    local log_type=${1:-all}
    local lines=${2:-20}
    
    print_message $BLUE "📋 服务日志 (最后${lines}行):"
    echo ""
    
    case $log_type in
        all|backend)
            if [ -f "$BACKEND_LOG" ]; then
                print_message $YELLOW "=== 后端主日志 ==="
                tail -n $lines "$BACKEND_LOG"
                echo ""
            fi
            
            if [ -f "$BACKEND_ERROR_LOG" ]; then
                print_message $RED "=== 后端错误日志 ==="
                tail -n $lines "$BACKEND_ERROR_LOG"
                echo ""
            fi
            
            # 显示业务日志
            if [ -f "$LOGS_DIR/business.log" ]; then
                print_message $BLUE "=== 业务操作日志 ==="
                tail -n $lines "$LOGS_DIR/business.log"
                echo ""
            fi
            
            # 显示API访问日志
            if [ -f "$LOGS_DIR/api_access.log" ]; then
                print_message $GREEN "=== API访问日志 ==="
                tail -n $lines "$LOGS_DIR/api_access.log"
                echo ""
            fi
            
            if [ "$log_type" = "backend" ]; then
                return
            fi
            ;;
    esac
    
    case $log_type in
        all|frontend)
            if [ -f "$FRONTEND_LOG" ]; then
                print_message $YELLOW "=== 前端日志 ==="
                tail -n $lines "$FRONTEND_LOG"
                echo ""
            fi
            
            if [ "$log_type" = "frontend" ]; then
                return
            fi
            ;;
    esac
    
    case $log_type in
        all|startup)
            if [ -f "$STARTUP_LOG" ]; then
                print_message $BLUE "=== 启动日志 ==="
                tail -n $lines "$STARTUP_LOG"
                echo ""
            fi
            ;;
    esac
    
    # 显示日志文件大小统计
    print_message $BLUE "📊 日志文件统计:"
    for log_file in "$BACKEND_LOG" "$BACKEND_ERROR_LOG" "$FRONTEND_LOG" "$STARTUP_LOG" "$LOGS_DIR/business.log" "$LOGS_DIR/api_access.log"; do
        if [ -f "$log_file" ]; then
            local size=$(du -h "$log_file" | cut -f1)
            local filename=$(basename "$log_file")
            echo "  $filename: $size"
        fi
    done
}

# 主函数
main() {
    local action=${1:-start}
    local log_type=${2:-all}
    local lines=${3:-20}
    
    # 记录脚本启动
    log_message "INFO" "脚本启动，操作: $action"
    
    case $action in
        start)
            print_message $GREEN "🚀 启动 Flink Web Analytics 服务..."
            echo ""
            
            # 检查系统依赖
            if ! check_dependencies; then
                exit 1
            fi
            
            start_backend
            echo ""
            start_frontend
            echo ""
            show_status
            echo ""
            print_message $GREEN "🎉 所有服务启动完成!"
            print_message $BLUE "💡 使用 '$0 status' 查看服务状态"
            print_message $BLUE "💡 使用 '$0 logs' 查看服务日志"
            print_message $BLUE "💡 使用 '$0 logs backend' 查看后端日志"
            print_message $BLUE "💡 使用 '$0 logs frontend' 查看前端日志"
            print_message $BLUE "💡 使用 '$0 stop' 停止所有服务"
            
            # 显示访问地址
            echo ""
            print_message $GREEN "🌐 访问地址:"
            local frontend_port=""
            for port in 5173 5174 5175; do
                if check_port $port; then
                    frontend_port=$port
                    break
                fi
            done
            
            if [ -n "$frontend_port" ]; then
                print_message $GREEN "   前端: http://localhost:$frontend_port"
            fi
            
            if check_port 8096; then
                print_message $GREEN "   后端API: http://localhost:8096/api"
                print_message $GREEN "   API文档: http://localhost:8096/api/docs"
            fi
            ;;
        stop)
            print_message $YELLOW "🛑 停止 Flink Web Analytics 服务..."
            echo ""
            stop_backend
            stop_frontend
            echo ""
            print_message $GREEN "✅ 所有服务已停止"
            log_message "INFO" "所有服务已停止"
            ;;
        restart)
            print_message $YELLOW "🔄 重启 Flink Web Analytics 服务..."
            echo ""
            stop_backend
            stop_frontend
            sleep 2
            echo ""
            
            # 检查系统依赖
            if ! check_dependencies; then
                exit 1
            fi
            
            start_backend
            echo ""
            start_frontend
            echo ""
            show_status
            log_message "INFO" "服务重启完成"
            ;;
        status)
            show_status
            ;;
        logs)
            show_logs "$log_type" "$lines"
            ;;
        clean)
            print_message $YELLOW "🧹 清理日志文件..."
            for log_file in "$BACKEND_LOG" "$BACKEND_ERROR_LOG" "$FRONTEND_LOG" "$STARTUP_LOG" "$LOGS_DIR/business.log" "$LOGS_DIR/api_access.log" "$LOGS_DIR/error.log"; do
                if [ -f "$log_file" ]; then
                    > "$log_file"
                    print_message $GREEN "✅ 已清理: $(basename "$log_file")"
                fi
            done
            log_message "INFO" "日志文件已清理"
            ;;
        help|--help|-h)
            show_help
            ;;
        *)
            print_message $RED "❌ 未知选项: $action"
            echo ""
            show_help
            exit 1
            ;;
    esac
}

# 捕获中断信号
trap 'echo ""; print_message $YELLOW "🛑 收到中断信号，正在停止服务..."; stop_backend; stop_frontend; exit 0' INT TERM

# 执行主函数
main "$@"
